#ifndef SNAPSHOTLISTFINDER_CPP
#define SNAPSHOTLISTFINDER_CPP

#include <iostream>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <vector>

#include <dirent.h>
#include <cstring>

#include "FileNameDecomposer/fnd.02.h"

using namespace std;


// SS List Finder
class SLF {
		
	public:

		vector<string> rawDirList; // full dir list
		vector<string> ssList; // ss list
		
		int getDirList(string dirName){
					
			DIR *dir;
			struct dirent *ent; // entry
			if ((dir=opendir(dirName.c_str())) == NULL) { perror("Error: can't open directory"); return -1; }
			
			rawDirList.erase(rawDirList.begin(), rawDirList.begin()+rawDirList.size());
			
			while ((ent=readdir(dir)) != NULL)
			rawDirList.push_back(string(ent->d_name));		
		
			closedir(dir);
			
		}
		
		void printDirList(){
			printf("\n");
			for (uint i = 0; i<rawDirList.size();i++)
			cout << rawDirList[i] << endl;
		}


		int getSSList(string fileName){
			
			FND fnd, _fnd, fnd_; // File Name Decomposer
			
			fnd.decompose(fileName);
			if (fnd.fileName=="") { 
				printf("\033[22;31merror: there is no 'fileName'\033[22;30m\n"); 
				return 0; 
			}
			
			ssList.erase(ssList.begin(), ssList.begin()+ssList.size());
			
			getDirList(fnd.path);
			
			// 1. if files seq. inside of SINGLE folder
			for (uint i = 0; i<rawDirList.size();i++) {
				
				_fnd.decompose(rawDirList[i]);
				
				// filter for seq. of SPLITED files with one folder
				if (fnd.fileID!="" && _fnd.baseFileName == fnd.baseFileName &&  fnd.partID==_fnd.partID && _fnd.partID!="") {
					ssList.push_back(fnd.path+rawDirList[i]);		
					//printf("#1 seq of splited files in one folder\n");
				}
				
				// filter for seq. of SINGLE files with one folder
				if (fnd.fileID!="" && fnd.partID=="" && _fnd.baseFileName == fnd.baseFileName && _fnd.partID=="") {
					ssList.push_back(fnd.path+rawDirList[i]);
					//printf("#2 seq of single files in one folder\n");
				}
				
			}
			
			// 2. if we have seq. of MULTIPLE folders
			// (lets find snapshots in seq of the upper folders)
			if (ssList.size()==1){
				
				getDirList(fnd.dirList[1]);
				
				// decompose upper folder name (we just remove '/' at the end)
				fnd_.decompose(fnd.dirList[0].substr(0, fnd.dirList[0].length()-1));
				
				for (uint i = 0; i<rawDirList.size();i++) {	
					
					_fnd.decompose(rawDirList[i]);
					
					if (_fnd.baseFileName == fnd_.baseFileName && fnd_.fileID!=_fnd.fileID)
						ssList.push_back(fnd.dirList[1]+rawDirList[i]+"/"+fnd.baseFileName+_fnd.fileID + fnd.partSep+fnd.partID);		
					
				}
				
			}
			
			// 3. if we have SINGLE file
			if (fnd.fileName!="" && fnd.fileID=="" && fnd.partID=="")
			ssList.push_back(fnd.path+fnd.fileName);	
			
			//exit(0);
			
			if (ssList.size()==0) 
			printf("\033[22;31merror: no snapshots were detected :: check file name\033[22;30m\n");
			
			// sort it :: 
			for (uint i=0; i<ssList.size()-1; i++) {	
				fnd.decompose(ssList[i]);
				uint ssNumMin=fnd.ifileID; uint jmin(0);
				for (uint j=i+1; j<ssList.size(); j++) {
					fnd.decompose(ssList[j]);
					if (fnd.ifileID < ssNumMin) { ssNumMin=fnd.ifileID; jmin=j;}
				}
				if (jmin) swap(&ssList[jmin], &ssList[i]);
			}
			
			
		}

		void print(){
			
			FND fnd; // File Name Decomposer
			
			for (uint i = 0; i<ssList.size(); i++) {
				
				fnd.decompose(ssList[i]);
				
				if (fnd.dirList.size()>1) 
				cout << "\033[22;37m" << fnd.dirList[1]	<< "\033[22;30m";
				
				if (fnd.dirList.size()>0) 
				cout << "\033[22;34m" << fnd.dirList2[0]	<< "\033[22;30m";
				
				cout << "\033[22;30m" << fnd.baseFileName	<< "\033[22;30m";
				cout << "\033[22;33m" << fnd.fileID			<< "\033[22;30m";
				cout << "\033[22;37m" << fnd.partSep		<< "\033[22;30m";
				cout << "\033[22;37m" << fnd.partID			<< "\033[22;30m";
				
				if (fnd.fileName!="" && fnd.fileID=="" && fnd.partID=="")
				cout << "\033[22;30m" << fnd.fileName	<< "\033[22;30m";
				
				cout << endl;
				
			}
		}

		// swap for sorting
		template <typename V>
		void swap(V *p1, V *p2) {
			V tmp = *p1;
			*p1 = *p2;
			*p2 = tmp;
		}

};

#endif